﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.AxHost;

namespace Revit同步插件.HttpServer
{
  public class ServiceHost<T> : ServiceHost
  {
    public ServiceHost() : base(typeof(T)) { }

    public ServiceHost(params string[] baseAddress) : base(typeof(T), Convert(baseAddress)) { }

    public ServiceHost(params Uri[] baseAddress) : base(typeof(T), baseAddress) { }

    public ServiceHost(T singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses) { }
    public bool EnableMetadataExchange
    {
      get
      {
        ServiceMetadataBehavior metadataBehavior;
        metadataBehavior = Description.Behaviors.Find<ServiceMetadataBehavior>();

        if (null == metadataBehavior)
        {
          return false;
        }

        return true;
      }
      set
      {
        if (State == CommunicationState.Opened)
        {
          throw new InvalidOperationException("Host is already opened");
        }
        ServiceMetadataBehavior metadataBehavior;
        metadataBehavior = Description.Behaviors.Find<ServiceMetadataBehavior>();

        if (metadataBehavior == null)
        {
          metadataBehavior = new ServiceMetadataBehavior();
          metadataBehavior.HttpGetEnabled = false;
          Description.Behaviors.Add(metadataBehavior);
        }


        if (value == true)
        {
          if (HasMexEndPoint == false)
          {
            AddAllMexEndPoints();
          }
        }
      }
    }


    public bool HasMexEndPoint
    {
      get
      {

        Predicate<ServiceEndpoint> mexEndPoint = delegate (ServiceEndpoint endpoint)
        {
          return endpoint.Contract.ContractType == typeof(IMetadataExchange);
        };
        return Description.Endpoints.ToList().Exists(mexEndPoint);
      }
    }


    public void AddAllMexEndPoints()
    {
      Debug.Assert(HasMexEndPoint == false);

      foreach (Uri baseAddress in BaseAddresses)
      {
        BindingElement be = null;
        switch (baseAddress.Scheme)
        {
          case "net.tcp": be = new TcpTransportBindingElement(); break;
          case "http": be = new HttpTransportBindingElement(); break;
          case "net.pipe": be = new NamedPipeTransportBindingElement(); break;
          case "https": be = new HttpsTransportBindingElement(); break;
        }

        if (null != be)
        {
          Binding binding = new CustomBinding(be);
          AddServiceEndpoint(typeof(IMetadataExchange), binding, "MEX");
        }
      }

    }





    static Uri[] Convert(string[] baseAddress)
    {
      Converter<string, Uri> convert = delegate (string address)
      {
        return new Uri(address);
      };

      return Array.ConvertAll(baseAddress, convert);
    }
  }
}
